package com.lagou.bio;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * BIO(blocking I/O) ： 同步阻塞，服务器实现模式为一个连接一个线程，即客户端有连接请求时服务器端就需要启动一个线程进行处理，
 * 如果这个连接不做任何事情会造成不必要的线程开销，可以通过线程池机制改善(实现多个客户连接服务器)。
 * BIO(同步并阻塞) 方式适用于连接数目比较小且固定的架构，这种方式对服务器资源要求比较高，并发局限于应用中，JDK1.4以前的唯一选择，但程序简单易理解
 */
public class BIOServer {

    public static void main(String[] args) throws Exception {
        // 创建线程池
        ExecutorService threadPool = Executors.newCachedThreadPool();
        // 创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(9999);
        while(true){
            Thread.sleep(1000);
            // 监听客户端
            System.out.println("等待连接....");
            final Socket socket = serverSocket.accept();
            System.out.println("连接到一个客户端");
            //就创建一个线程，与之通讯(单独写一个方法)
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    //可以和客户端通讯
                    handle(socket);
                }
            });
        }
    }

    //编写一个handler方法，和客户端通讯
    private static void handle(Socket socket)  { ;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            System.out.println("线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());
            //通过socket 获取输入流
            inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int read = inputStream.read(bytes);
            System.out.println("客户端:" + new String(bytes, 0, read));
            // 取出输出流并返回信息
            outputStream = socket.getOutputStream();
            outputStream.write("没钱".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
